package com.zlzlib.librxoknet.pro;

import android.os.SystemClock;


import com.zlzlib.librx.ProgressInfo;
import com.zlzlib.librx.listener.ProgressListener;

import java.io.IOException;

import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import okhttp3.MediaType;
import okhttp3.ResponseBody;
import okio.Buffer;
import okio.BufferedSource;
import okio.ForwardingSource;
import okio.Okio;
import okio.Source;

/**
 * 带进度的返回体 下载
 * Created by zlz on 2019/2/28.
 */
public class ProResponseBody extends ResponseBody {

    private final ResponseBody responseBody;
    private final ProgressListener<Buffer> listener;
    private BufferedSource bufferedSource;
    private final long freshTime;
    private final ProgressInfo<Buffer> info;

    public ProResponseBody(ResponseBody responseBody, ProgressListener<Buffer> listener, long freshTime) {
        this.responseBody = responseBody;
        this.listener = listener;
        this.freshTime = freshTime;
        info = new ProgressInfo<>(System.currentTimeMillis());
        info.setContentLength(contentLength());
        //第一次直接返回总长度
        AndroidSchedulers.mainThread().scheduleDirect(() -> ProResponseBody.this.listener.updateDown(info));
    }

    @Override
    public MediaType contentType() {
        return responseBody.contentType();
    }

    @Override
    public long contentLength() {
        return responseBody.contentLength();
    }

    @Override
    public BufferedSource source() {
        if (bufferedSource == null) {
            bufferedSource = Okio.buffer(source(responseBody.source()));
        }
        return bufferedSource;
    }

    private Source source(Source source) {
        return new ForwardingSource(source) {
            //当前数据总大小
            private long currLength = 0L;
            private long lastRefreshTime = SystemClock.elapsedRealtime();  //最后一次刷新的时间
            private long tempSize = 0L;

            @Override
            public long read(Buffer sink, long byteCount) throws IOException {
                long bytesRead = super.read(sink, byteCount);
                if (listener == null || info.isFinish()) {
                    return bytesRead;
                }
                currLength += bytesRead != -1 ? bytesRead : 0;
                tempSize += bytesRead != -1 ? bytesRead : 0;
                //判断刷新时间
                long curTime = SystemClock.elapsedRealtime();
                long intervalTime = curTime - lastRefreshTime;
                if (bytesRead == -1 || currLength >= info.getContentLength() || intervalTime >= freshTime) {
                    info.setData(sink);
                    info.setEachBytes(currLength == -1 ? -1 : tempSize);
                    info.setCurrentBytes(currLength);
                    info.setIntervalTime(intervalTime);
                    info.setFinish(currLength >= info.getContentLength());
                    //发送到主线程
                    AndroidSchedulers.mainThread().scheduleDirect(() -> listener.updateDown(info));
                    tempSize = 0;
                    lastRefreshTime = curTime;
                }
                return bytesRead;
            }
        };
    }
}
